home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / gfx / conv / jpegV5Asrc.lha / jpeg-5a / jdcoefct.c < prev    next >
C/C++ Source or Header  |  1994-07-16  |  12KB  |  360 lines

  1. /*
  2.  * jdcoefct.c
  3.  *
  4.  * Copyright (C) 1994, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains the coefficient buffer controller for decompression.
  9.  * This controller is the top level of the JPEG decompressor proper.
  10.  * The coefficient buffer lies between entropy decoding and inverse-DCT steps.
  11.  */
  12.  
  13. #define JPEG_INTERNALS
  14. #include "jinclude.h"
  15. #include "jpeglib.h"
  16.  
  17.  
  18. /* Private buffer controller object */
  19.  
  20. typedef struct {
  21.   struct jpeg_d_coef_controller pub; /* public fields */
  22.  
  23.   JDIMENSION MCU_col_num;    /* saves next MCU column to process */
  24.   JDIMENSION MCU_row_num;    /* keep track of MCU row # within image */
  25.  
  26.   /* In single-pass modes without block smoothing, it's sufficient to buffer
  27.    * just one MCU (although this may prove a bit slow in practice).
  28.    * We allocate a workspace of MAX_BLOCKS_IN_MCU coefficient blocks,
  29.    * and let the entropy decoder write into that workspace each time.
  30.    * (On 80x86, the workspace is FAR even though it's not really very big;
  31.    * this is to keep the module interfaces unchanged when a large coefficient
  32.    * buffer is necessary.)
  33.    * In multi-pass modes, this array points to the current MCU's blocks
  34.    * within the virtual arrays.
  35.    */
  36.   JBLOCKROW MCU_buffer[MAX_BLOCKS_IN_MCU];
  37.  
  38.   /* In multi-pass modes, we need a virtual block array for each component. */
  39.   jvirt_barray_ptr whole_image[MAX_COMPONENTS];
  40. } my_coef_controller;
  41.  
  42. typedef my_coef_controller * my_coef_ptr;
  43.  
  44.  
  45. /* Forward declarations */
  46. METHODDEF boolean decompress_data
  47.     JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
  48. #ifdef D_MULTISCAN_FILES_SUPPORTED
  49. METHODDEF boolean decompress_read
  50.     JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
  51. METHODDEF boolean decompress_output
  52.     JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
  53. #endif
  54.  
  55.  
  56. /*
  57.  * Initialize for a processing pass.
  58.  */
  59.  
  60. METHODDEF void
  61. start_pass_coef (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
  62. {
  63.   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  64.  
  65.   coef->MCU_col_num = 0;
  66.   coef->MCU_row_num = 0;
  67.  
  68.   switch (pass_mode) {
  69.   case JBUF_PASS_THRU:
  70.     if (coef->whole_image[0] != NULL)
  71.       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  72.     coef->pub.decompress_data = decompress_data;
  73.     break;
  74. #ifdef D_MULTISCAN_FILES_SUPPORTED
  75.   case JBUF_SAVE_SOURCE:
  76.     if (coef->whole_image[0] == NULL)
  77.       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  78.     coef->pub.decompress_data = decompress_read;
  79.     break;
  80.   case JBUF_CRANK_DEST:
  81.     if (coef->whole_image[0] == NULL)
  82.       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  83.     coef->pub.decompress_data = decompress_output;
  84.     break;
  85. #endif
  86.   default:
  87.     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  88.     break;
  89.   }
  90. }
  91.  
  92.  
  93. /*
  94.  * Process some data in the single-pass case.
  95.  * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
  96.  * Returns TRUE if it completed a row, FALSE if not (suspension).
  97.  *
  98.  * NB: output_buf contains a plane for each component in image.
  99.  * For single pass, this is the same as the components in the scan.
  100.  */
  101.  
  102. METHODDEF boolean
  103. decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
  104. {
  105.   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  106.   JDIMENSION MCU_col_num;    /* index of current MCU within row */
  107.   JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
  108.   JDIMENSION last_MCU_row = cinfo->MCU_rows_in_scan - 1;
  109.   int blkn, ci, xindex, yindex, useful_width;
  110.   JSAMPARRAY output_ptr;
  111.   JDIMENSION start_col, output_col;
  112.   jpeg_component_info *compptr;
  113.   inverse_DCT_method_ptr inverse_DCT;
  114.  
  115.   /* Loop to process as much as one whole MCU row */
  116.  
  117.   for (MCU_col_num = coef->MCU_col_num; MCU_col_num <= last_MCU_col;
  118.        MCU_col_num++) {
  119.  
  120.     /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
  121.     jzero_far((void FAR *) coef->MCU_buffer[0],
  122.           (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
  123.     if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
  124.       /* Suspension forced; return with row unfinished */
  125.       coef->MCU_col_num = MCU_col_num; /* update my state */
  126.       return FALSE;
  127.     }
  128.  
  129.     /* Determine where data should go in output_buf and do the IDCT thing.
  130.      * We skip dummy blocks at the right and bottom edges (but blkn gets
  131.      * incremented past them!).  Note the inner loop relies on having
  132.      * allocated the MCU_buffer[] blocks sequentially.
  133.      */
  134.     blkn = 0;            /* index of current DCT block within MCU */
  135.     for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
  136.       compptr = cinfo->cur_comp_info[ci];
  137.       /* Don't bother to IDCT an uninteresting component. */
  138.       if (! compptr->component_needed) {
  139.     blkn += compptr->MCU_blocks;
  140.     continue;
  141.       }
  142.       inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
  143.       useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
  144.                           : compptr->last_col_width;
  145.       output_ptr = output_buf[ci];
  146.       start_col = MCU_col_num * compptr->MCU_sample_width;
  147.       for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
  148.     if (coef->MCU_row_num < last_MCU_row ||
  149.         yindex < compptr->last_row_height) {
  150.       output_col = start_col;
  151.       for (xindex = 0; xindex < useful_width; xindex++) {
  152.         (*inverse_DCT) (cinfo, compptr,
  153.                 (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
  154.                 output_ptr, output_col);
  155.         output_col += compptr->DCT_scaled_size;
  156.       }
  157.     }
  158.     blkn += compptr->MCU_width;
  159.     output_ptr += compptr->DCT_scaled_size;
  160.       }
  161.     }
  162.   }
  163.  
  164.   /* We finished the row successfully */
  165.   coef->MCU_col_num = 0;    /* prepare for next row */
  166.   coef->MCU_row_num++;
  167.   return TRUE;
  168. }
  169.  
  170.  
  171. #ifdef D_MULTISCAN_FILES_SUPPORTED
  172.  
  173. /*
  174.  * Process some data: handle an input pass for a multiple-scan file.
  175.  * We read the equivalent of one fully interleaved MCU row ("iMCU" row)
  176.  * per call, ie, v_samp_factor block rows for each component in the scan.
  177.  * No data is returned; we just stash it in the virtual arrays.
  178.  *
  179.  * Returns TRUE if it completed a row, FALSE if not (suspension).
  180.  * Currently, the suspension case is not supported.
  181.  */
  182.  
  183. METHODDEF boolean
  184. decompress_read (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
  185. {
  186.   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  187.   JDIMENSION MCU_col_num;    /* index of current MCU within row */
  188.   int blkn, ci, xindex, yindex, yoffset, num_MCU_rows;
  189.   JDIMENSION total_width, remaining_rows, start_col;
  190.   JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
  191.   JBLOCKROW buffer_ptr;
  192.   jpeg_component_info *compptr;
  193.  
  194.   /* Align the virtual buffers for the components used in this scan. */
  195.   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
  196.     compptr = cinfo->cur_comp_info[ci];
  197.     buffer[ci] = (*cinfo->mem->access_virt_barray)
  198.       ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
  199.        coef->MCU_row_num * compptr->v_samp_factor, TRUE);
  200.     /* Entropy decoder expects buffer to be zeroed. */
  201.     total_width = (JDIMENSION) jround_up((long) compptr->width_in_blocks,
  202.                      (long) compptr->h_samp_factor);
  203.     for (yindex = 0; yindex < compptr->v_samp_factor; yindex++) {
  204.       jzero_far((void FAR *) buffer[ci][yindex], 
  205.         (size_t) (total_width * SIZEOF(JBLOCK)));
  206.     }
  207.   }
  208.  
  209.   /* In an interleaved scan, we process exactly one MCU row.
  210.    * In a noninterleaved scan, we need to process v_samp_factor MCU rows,
  211.    * each of which contains a single block row.
  212.    */
  213.   if (cinfo->comps_in_scan == 1) {
  214.     compptr = cinfo->cur_comp_info[0];
  215.     num_MCU_rows = compptr->v_samp_factor;
  216.     /* but watch out for the bottom of the image */
  217.     remaining_rows = cinfo->MCU_rows_in_scan -
  218.              coef->MCU_row_num * compptr->v_samp_factor;
  219.     if (remaining_rows < (JDIMENSION) num_MCU_rows)
  220.       num_MCU_rows = (int) remaining_rows;
  221.   } else {
  222.     num_MCU_rows = 1;
  223.   }
  224.  
  225.   /* Loop to process one whole iMCU row */
  226.   for (yoffset = 0; yoffset < num_MCU_rows; yoffset++) {
  227.     for (MCU_col_num = 0; MCU_col_num < cinfo->MCUs_per_row; MCU_col_num++) {
  228.       /* Construct list of pointers to DCT blocks belonging to this MCU */
  229.       blkn = 0;            /* index of current DCT block within MCU */
  230.       for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
  231.     compptr = cinfo->cur_comp_info[ci];
  232.     start_col = MCU_col_num * compptr->MCU_width;
  233.     for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
  234.       buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
  235.       for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
  236.         coef->MCU_buffer[blkn++] = buffer_ptr++;
  237.       }
  238.     }
  239.       }
  240.       /* Try to fetch the MCU. */
  241.       if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
  242.     ERREXIT(cinfo, JERR_CANT_SUSPEND); /* not supported */
  243.       }
  244.     }
  245.   }
  246.  
  247.   coef->MCU_row_num++;
  248.   return TRUE;
  249. }
  250.  
  251.  
  252. /*
  253.  * Process some data: output from the virtual arrays after reading is done.
  254.  * Always emits one fully interleaved MCU row ("iMCU" row).
  255.  * Always returns TRUE --- suspension is not possible.
  256.  *
  257.  * NB: output_buf contains a plane for each component in image.
  258.  */
  259.  
  260. METHODDEF boolean
  261. decompress_output (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
  262. {
  263.   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  264.   JDIMENSION last_MCU_row = cinfo->total_iMCU_rows - 1;
  265.   JDIMENSION block_num;
  266.   int ci, block_row, block_rows;
  267.   JBLOCKARRAY buffer;
  268.   JBLOCKROW buffer_ptr;
  269.   JSAMPARRAY output_ptr;
  270.   JDIMENSION output_col;
  271.   jpeg_component_info *compptr;
  272.   inverse_DCT_method_ptr inverse_DCT;
  273.  
  274.   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  275.        ci++, compptr++) {
  276.     /* Don't bother to IDCT an uninteresting component. */
  277.     if (! compptr->component_needed)
  278.       continue;
  279.     /* Align the virtual buffer for this component. */
  280.     buffer = (*cinfo->mem->access_virt_barray)
  281.       ((j_common_ptr) cinfo, coef->whole_image[ci],
  282.        coef->MCU_row_num * compptr->v_samp_factor, FALSE);
  283.     /* Count non-dummy DCT block rows in this iMCU row. */
  284.     if (coef->MCU_row_num < last_MCU_row)
  285.       block_rows = compptr->v_samp_factor;
  286.     else {
  287.       block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
  288.       if (block_rows == 0) block_rows = compptr->v_samp_factor;
  289.     }
  290.     inverse_DCT = cinfo->idct->inverse_DCT[ci];
  291.     output_ptr = output_buf[ci];
  292.     /* Loop over all DCT blocks to be processed. */
  293.     for (block_row = 0; block_row < block_rows; block_row++) {
  294.       buffer_ptr = buffer[block_row];
  295.       output_col = 0;
  296.       for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
  297.     (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
  298.             output_ptr, output_col);
  299.     buffer_ptr++;
  300.     output_col += compptr->DCT_scaled_size;
  301.       }
  302.       output_ptr += compptr->DCT_scaled_size;
  303.     }
  304.   }
  305.  
  306.   coef->MCU_row_num++;
  307.   return TRUE;
  308. }
  309.  
  310. #endif /* D_MULTISCAN_FILES_SUPPORTED */
  311.  
  312.  
  313. /*
  314.  * Initialize coefficient buffer controller.
  315.  */
  316.  
  317. GLOBAL void
  318. jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
  319. {
  320.   my_coef_ptr coef;
  321.   int ci, i;
  322.   jpeg_component_info *compptr;
  323.   JBLOCKROW buffer;
  324.  
  325.   coef = (my_coef_ptr)
  326.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  327.                 SIZEOF(my_coef_controller));
  328.   cinfo->coef = (struct jpeg_d_coef_controller *) coef;
  329.   coef->pub.start_pass = start_pass_coef;
  330.  
  331.   /* Create the coefficient buffer. */
  332.   if (need_full_buffer) {
  333. #ifdef D_MULTISCAN_FILES_SUPPORTED
  334.     /* Allocate a full-image virtual array for each component, */
  335.     /* padded to a multiple of samp_factor DCT blocks in each direction. */
  336.     /* Note memmgr implicitly pads the vertical direction. */
  337.     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  338.      ci++, compptr++) {
  339.       coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
  340.     ((j_common_ptr) cinfo, JPOOL_IMAGE,
  341.      (JDIMENSION) jround_up((long) compptr->width_in_blocks,
  342.                 (long) compptr->h_samp_factor),
  343.      compptr->height_in_blocks,
  344.      (JDIMENSION) compptr->v_samp_factor);
  345.     }
  346. #else
  347.     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  348. #endif
  349.   } else {
  350.     /* We only need a single-MCU buffer. */
  351.     buffer = (JBLOCKROW)
  352.       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  353.                   MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
  354.     for (i = 0; i < MAX_BLOCKS_IN_MCU; i++) {
  355.       coef->MCU_buffer[i] = buffer + i;
  356.     }
  357.     coef->whole_image[0] = NULL; /* flag for no virtual arrays */
  358.   }
  359. }
  360.